package org.desktop.web.server;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.text.StrSubstitutor;
import org.desktop.web.client.project.service.ProjectService;
import org.desktop.web.server.locator.ServiceLocator;
import org.desktop.web.server.locator.ServiceLocator.ServiceName;
import org.desktop.web.server.util.RpcUtil;
import org.desktop.web.shared.domain.entities.Project;
import org.desktop.web.shared.domain.entities.SubProject;
import org.json.JSONObject;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sencha.gxt.data.shared.loader.PagingLoadConfig;
import com.sencha.gxt.data.shared.loader.PagingLoadResult;

public class ProjectServiceImpl extends AbstractPagingService<Project> 
implements
		ProjectService {

	private String projectses = RpcUtil.createUrlService(ServiceLocator.find(ServiceName.TIMESHEET_SERVICE),"projectses");
	private String delsubprojectses = RpcUtil.createUrlService(ServiceLocator.find(ServiceName.TIMESHEET_SERVICE),"subprojectses/${id}");
	private String delprojectses = RpcUtil.createUrlService(ServiceLocator.find(ServiceName.TIMESHEET_SERVICE),"projectses/${id}");

	private String subProjectsByProjectId = RpcUtil.createUrlService(ServiceLocator.find(ServiceName.TIMESHEET_SERVICE),"subprojectses/project/${idProject}");

	private String subprojectses = RpcUtil.createUrlService(ServiceLocator.find(ServiceName.TIMESHEET_SERVICE),"subprojectses");
	private String jsonHeader = "application/json";

	@Override
	public PagingLoadResult<Project> getProjects(final String token,
			PagingLoadConfig loadConfig) throws Exception {
		try {
			Map<String,String> headers = new HashMap<String, String>(){
				{
					put("token", token);
				}
			};
			return getDatas(headers, loadConfig, projectses);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	@Override
	public PagingLoadResult<SubProject> getSubProjectsByIdProject(final String token,
			String idProject, PagingLoadConfig loadConfig) throws Exception {
		Map<String,String> headers = new HashMap<String, String>(){
			{
				put("token",token);
			}
		};
		Map<String, String> valueMap = new HashMap<String, String>();
		valueMap.put("idProject", idProject);
		StrSubstitutor substitutor = new StrSubstitutor(valueMap);
		String url = substitutor.replace(subProjectsByProjectId);
		
		return new AbstractPagingService<SubProject>() {

			@Override
			public Class getType() {
				// TODO Auto-generated method stub
				return SubProject.class;
			}
		}.getDatas(headers, loadConfig, url);
		
//		PageEntity<SubProject> entities;
//		List<SubProject> res;
//		try {
//			int activePage = RpcUtil.getActivePage(loadConfig);
//			List<SortInfo> sorts = (List<SortInfo>) loadConfig.getSortInfo();
//			StringBuilder sortUrl = RpcUtil.createSortUrl(sorts);
//			String paginationUrl = RpcUtil.createPaginationUrl(
//					subProjectsByProjectId, loadConfig, activePage, sortUrl);
//
//			Map<String, String> valueMap = new HashMap<String, String>();
//			valueMap.put("idProject", idProject);
//			StrSubstitutor substitutor = new StrSubstitutor(valueMap);
//			String url = substitutor.replace(paginationUrl);
//			System.out.println("URL: " + url);
//			URL _url = new URL(url);
//			HttpURLConnection con = RpcUtil.getUrlConnection(_url, "GET");
//
//			RpcUtil.addFilters(loadConfig, con);
//
//			InputStream in = con.getInputStream();
//			String jsonResult = IOUtils.toString(in);
//			
//			System.out.println(jsonResult);
//			
//			ObjectMapper map = new ObjectMapper();
//			 entities = map.readValue(jsonResult.toString(),
//					new TypeReference<PageEntity<SubProject>>() {
//					});
//			List<SubProject> projects = entities.getContent();
//			JSONArray json = new JSONObject(jsonResult).getJSONArray("content");
//			for (int i = 0; i < json.length(); i++) {
//				JSONObject obj = json.getJSONObject(i);
//				obj.remove("idProject");
//
//			}
//			res = entities.getContent();
//			System.out.println(entities.getContent());
//			return new PagingLoadResultBean<>(res, entities.getTotalElements(),
//					entities.getNumber());
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return null;
	}

	@Override
	public boolean saveSubProject(String token, int idProject, SubProject sub)
			throws Exception {

		HttpURLConnection con = RpcUtil.getUrlConnection(
				new URL(subprojectses), "POST");
		System.out.println("Calling.... " + subprojectses);
		con.setRequestProperty("Accept", jsonHeader);
		con.setRequestProperty("token", token);

		con.setRequestProperty("Content-Type", "application/octect-stream");

		ObjectMapper mapper = new ObjectMapper();
		String json = mapper.writeValueAsString(sub);
		JSONObject obj = new JSONObject(json).put("idProject",
				new JSONObject().put("id", idProject));
		System.out.println(obj.toString());

		OutputStream out = con.getOutputStream();
		out.write(obj.toString().getBytes());
		out.close();
		InputStream in = con.getInputStream();
		int responseCode = con.getResponseCode();
		System.out
				.println("ProjectServiceImpl.saveSubProject()::response code: "
						+ con.getResponseCode());
		in.close();
		return responseCode == 201;
	}

	@Override
	public boolean saveProject(Project project) throws Exception {
		HttpURLConnection con = RpcUtil.getUrlConnection(new URL(projectses),
				"POST");
		System.out.println("Calling.... " + projectses);
		con.setRequestProperty("Accept", jsonHeader);
		RpcUtil.setToken(con, getThreadLocalRequest());

		// con.setRequestProperty("token", );

		con.setRequestProperty("Content-Type", "application/octect-stream");

		ObjectMapper mapper = new ObjectMapper();
		String json = mapper.writeValueAsString(project);
		System.out.println(json);

		OutputStream out = con.getOutputStream();
		out.write(new JSONObject(json).toString().getBytes());
		out.close();
		InputStream in = con.getInputStream();
		int responseCode = con.getResponseCode();
		System.out
				.println("ProjectServiceImpl.saveSubProject()::response code: "
						+ con.getResponseCode());
		in.close();
		return responseCode == 201;
	}

	@Override
	public boolean deleteSubProject(int id) throws Exception {
		Map<String, String> map = new HashMap<String, String>();
		map.put("id", Integer.toString(id));
		StrSubstitutor sub = new StrSubstitutor(map);
		HttpURLConnection con = RpcUtil.getUrlConnection(
				new URL(sub.replace(delsubprojectses)), "DELETE");

		con.setRequestProperty("Accept", jsonHeader);
		RpcUtil.setToken(con, getThreadLocalRequest());
		InputStream in = con.getInputStream();
		int code = con.getResponseCode();
		in.close();
		// TODO Auto-generated method stub
		return code == 200;
	}

	@Override
	public boolean deleteProject(Project selectedItem) throws Exception {
		Map<String, String> map = new HashMap<String, String>();
		map.put("id", Integer.toString(selectedItem.getId()));
		StrSubstitutor sub = new StrSubstitutor(map);
		HttpURLConnection con = RpcUtil.getUrlConnection(
				new URL(sub.replace(delprojectses)), "DELETE");

		con.setRequestProperty("Accept", jsonHeader);
		RpcUtil.setToken(con, getThreadLocalRequest());
		InputStream in = con.getInputStream();
		int code = con.getResponseCode();
		in.close();
		// TODO Auto-generated method stub
		return code == 200;
	}

	@Override
	public Class<?> getType() {
		// TODO Auto-generated method stub
		return Project.class;
	}

}
